﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

using Perseus;
using Perseus.Data;

namespace Hetymine.Executioner {
    public static class Styles {
        public static void OuterBorder(Border b) {
            Styles.OuterBorder(b, Executioner.Config);
        }
        public static void OuterBorder(Border b, IniFile config) {
            int width = config.GetInt("Appearance", "Outer Border Width", 2);
            b.BorderThickness = new Thickness(width);

            string colour = config.GetString("Appearance", "Outer Border Colour", "#313131");
            b.BorderBrush = new SolidColorBrush(Styles.HexToColour(colour));
            if (width > 0) {
                b.Background = new SolidColorBrush(Styles.HexToColour(colour));
            }
            else {
                b.Background = new SolidColorBrush(Colors.Transparent);
            }

            width = config.GetInt("Appearance", "Outer Border Radius", 6);
            b.CornerRadius = new CornerRadius(width);
        }
        public static void InnerBorder(Border b) {
            Styles.InnerBorder(b, Executioner.Config);
        }
        public static void InnerBorder(Border b, IniFile config) {
            int width = config.GetInt("Appearance", "Inner Border Width", 2);
            b.BorderThickness = new Thickness(width);

            string colour = config.GetString("Appearance", "Inner Border Colour", "#FBC23E");
            b.BorderBrush = new SolidColorBrush(Styles.HexToColour(colour));

            width = config.GetInt("Appearance", "Inner Border Radius", 4);
            b.CornerRadius = new CornerRadius(width);

            colour = config.GetString("Appearance", "Background Colour", "#313131");
            b.Background = new SolidColorBrush(Styles.HexToColour(colour));
        }

        public static void TextBox(TextBox t) {
            Styles.TextBox(t, Executioner.Config);
        }
        public static void TextBox(TextBox t, IniFile config) {
            t.BorderThickness = new Thickness(0);

            // Alignment and Padding
            int padding = config.GetInt("Appearance", "Padding", 3);
            t.Margin = new Thickness(padding);

            System.Drawing.Font f = Styles.Font(config);

            t.FontFamily = new FontFamily(f.FontFamily.Name);
            t.FontSize = f.Size;
            if (f.Bold) {
                t.FontWeight = FontWeights.Bold;
            }
            else {
                t.FontWeight = FontWeights.Regular;
            }
            if (f.Italic) {
                t.FontStyle = FontStyles.Italic;
            }
            else {
                t.FontStyle = FontStyles.Normal;
            }

            string colour = config.GetString("Appearance", "Background Colour", "#313131");
            t.Background = new SolidColorBrush(Styles.HexToColour(colour));

            colour = config.GetString("Appearance", "Foreground Colour", "#FBC23E");
            t.Foreground = new SolidColorBrush(Styles.HexToColour(colour));
        }

        public static Color HexToColour(string hex) {
            string alpha, red, green, blue;
            byte a, r, g, b;

            if (hex.Length == 9) {
                alpha = hex.Substring(1, 2);
                a = Convert.ToByte(alpha, 16);

                red = hex.Substring(3, 2);
                r = Convert.ToByte(red, 16);

                green = hex.Substring(5, 2);
                g = Convert.ToByte(green, 16);

                blue = hex.Substring(7, 2);
                b = Convert.ToByte(blue, 16);

                return Color.FromArgb(a, r, g, b);
            }

            if (hex.Length == 7) {
                red = hex.Substring(1, 2);
                r = Convert.ToByte(red, 16);

                green = hex.Substring(3, 2);
                g = Convert.ToByte(green, 16);

                blue = hex.Substring(5, 2);
                b = Convert.ToByte(blue, 16);

                return Color.FromRgb(r, g, b);
            }

            red = hex.Substring(1, 1);
            r = Convert.ToByte(red + red, 16);

            green = hex.Substring(2, 1);
            g = Convert.ToByte(green + green, 16);

            blue = hex.Substring(3, 1);
            b = Convert.ToByte(blue + blue, 16);

            return Color.FromRgb(r, g, b);
        }

        public static System.Drawing.Font Font() {
            return Styles.Font(Executioner.Config);
        }
        public static System.Drawing.Font Font(IniFile config) {
            System.Drawing.FontStyle style = System.Drawing.FontStyle.Regular;

            string[] styles = PString.Split(
                config.GetString("Appearance", "Font Style", "regular"),
                ",",
                SplitOptions.Trim
            );
            foreach (string s in styles) {
                if (s.ToLower() == "bold") {
                    style |= System.Drawing.FontStyle.Bold;
                }

                if (s.ToLower() == "italic") {
                    style |= System.Drawing.FontStyle.Italic;
                }
            }

            string font = config.GetString("Appearance", "Font Family", "Microsoft Sans Serif");
            int size = config.GetInt("Appearance", "Font Size", 14);

            return new System.Drawing.Font(font, size, style);
        }

        public static System.Windows.Forms.Screen Display() {
            return Styles.Display(Executioner.Config);
        }
        public static System.Windows.Forms.Screen Display(IniFile config) {
            int monitor = config.GetInt("Behaviour", "Display", -1);
            return Styles.Display(monitor);
        }
        public static System.Windows.Forms.Screen Display(int monitor) {
            if (monitor >= 0 && monitor < System.Windows.Forms.Screen.AllScreens.Length) {
                return System.Windows.Forms.Screen.AllScreens[monitor];
            }

            return System.Windows.Forms.Screen.PrimaryScreen;
        }

        public static Point Position(double width, double height) {
            string alignment = Executioner.Config.GetString("Appearance", "Alignment", "centre centre").ToLower();
            int margin = Executioner.Config.GetInt("Appearance", "Margin", 10);

            return Styles.Position(width, height, alignment, margin);
        }
        public static Point Position(double width, double height, string alignment, int margin) {
            System.Drawing.Rectangle r = Styles.Display().WorkingArea;

            int x = r.X;
            int y = r.Y;

            switch (alignment) {
                case "left top":
                case "top left":
                    x += margin;
                    y += margin;
                    break;
                case "centre top":
                case "center top":
                case "top centre":
                case "top center":
                    x += (int)((r.Width - width) / 2);
                    y += margin;
                    break;
                case "right top":
                case "top right":
                    x += (r.Width - (int)width - margin);
                    y += margin;
                    break;
                case "left centre":
                case "left center":
                case "centre left":
                case "center left":
                    x += margin;
                    y += (int)((r.Height - height) / 2);
                    break;
                case "right centre":
                case "right center":
                case "centre right":
                case "center right":
                    x += (r.Width - (int)width - margin);
                    y += (int)((r.Height - height) / 2);
                    break;
                case "left bottom":
                case "bottom left":
                    x += margin;
                    y += (r.Height - (int)height - margin);
                    break;
                case "centre bottom":
                case "center bottom":
                case "bottom centre":
                case "bottom center":
                    x += (int)((r.Width - width) / 2);
                    y += (r.Height - (int)height - margin);
                    break;
                case "right bottom":
                case "bottom right":
                    x += (r.Width - (int)width - margin);
                    y += (r.Height - (int)height - margin);
                    break;
                default: // Centre
                    x += (int)((r.Width - width) / 2);
                    y += (int)((r.Height - height) / 2);
                    break;
            }

            return new Point(x, y);
        }
    }
}
